package com.nwpu.hass.serviceimpl;

import com.nwpu.hass.domain.DeviceEntity;
import com.nwpu.hass.domain.JsonResponse.ApplyEntity;
import com.nwpu.hass.domain.JsonResponse.IdleDevicesGroupResponse;
import com.nwpu.hass.domain.JsonResponse.LastFourDayLentResponse;
import com.nwpu.hass.domain.JsonResponse.UsedDeviceFreqResponse;
import com.nwpu.hass.domain.RegisterformEntity;
import com.nwpu.hass.domain.UserEntity;
import com.nwpu.hass.repository.MessageRepository;
import com.nwpu.hass.repository.RegisterformRepository;
import com.nwpu.hass.repository.DeviceRepository;
import com.nwpu.hass.repository.UserRepository;
import com.nwpu.hass.service.MessageService;
import com.nwpu.hass.service.RegisterformService;
import com.nwpu.hass.utils.Status;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.relational.core.sql.In;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.spi.RegisterableService;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class RegisterformServiceImpl implements RegisterformService {

    @Resource
    private RegisterformRepository registerformRepository;
    @Resource
    private DeviceRepository deviceRepository;
    @Resource
    private UserRepository userRepository;
    @Resource
    private MessageService messageService;

    @Autowired
    private EntityManager entityManager;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public ApplyEntity findOneRegisterById(Long recordId) {

        Optional<RegisterformEntity> registerformEntityOptional = registerformRepository.findById(recordId);
        RegisterformEntity registerformEntity;
        if (registerformEntityOptional.isPresent()) {
            registerformEntity = registerformEntityOptional.get();
            DeviceEntity deviceEntity = deviceRepository.findDeviceEntityByDeviceId(registerformEntity.getDevice());
            UserEntity userEntity = userRepository.findUserEntityByUserid(registerformEntity.getBorrowPerson());
            Timestamp timestamp;
            if (deviceEntity.getStatus() == -1 || deviceEntity.getStatus() == 2) {
                timestamp = registerformEntity.getBorrowTime();
            } else {
                timestamp = registerformEntity.getReturnTime();
            }
            return new ApplyEntity(userEntity, timestamp, deviceEntity, 0L);
        }
        return null;
    }

    @Override
    public DeviceEntity checkOneRegisterById(Long id, boolean status) {

        Optional<RegisterformEntity> registerformEntity = registerformRepository.findById(id);
        if (registerformEntity.isPresent()) {
            RegisterformEntity registerform = registerformEntity.get();
            DeviceEntity deviceEntity = deviceRepository.findDeviceEntityByDeviceId(registerform.getDevice());
            boolean isBorrow = false;
            if(deviceEntity.getStatus() == Status.ONBORROW.getStatus()) {
                isBorrow = true;
            }
            deviceEntity.passOrNot(status);
            // 归还成功、借出失败
            String msgContent;
            if (deviceEntity.getStatus() == 0) {
                deviceEntity.setPosition("仓库");
                if(isBorrow) {
                    msgContent = "您于" + sdf.format(registerform.getBorrowTime()) + "申请借用的" +
                            deviceEntity.getFamily() +deviceEntity.getType() + "被管理员拒绝了:(";
                } else {
                    msgContent = "您于" + sdf.format(registerform.getBorrowTime()) + "申请归还的" +
                            deviceEntity.getFamily() +deviceEntity.getType() + "被管理员接受了:)";
                }
            } else if (deviceEntity.getStatus() == 2) {  // 归还失败，借出成功
                Long userId = registerform.getBorrowPerson();
                UserEntity userEntity = userRepository.findUserEntityByUserid(userId);
                deviceEntity.setPosition(userEntity.getDepwork());
                if(isBorrow) {
                    msgContent = "您于" + sdf.format(registerform.getBorrowTime()) + "申请借用的" +
                            deviceEntity.getFamily() +deviceEntity.getType() + "被管理员通过了:)";
                } else {
                    msgContent = "您于" + sdf.format(registerform.getBorrowTime()) + "申请归还的" +
                            deviceEntity.getFamily() +deviceEntity.getType() + "被管理员拒绝了:(";
                }
            } else {
                return deviceRepository.save(deviceEntity);
            }

            messageService.addMessage(registerform.getBorrowPerson(), msgContent);
            return deviceRepository.save(deviceEntity);
        }
        return null;
    }


    @Override
    public List<UsedDeviceFreqResponse> getDeviceByFreq() {

        Query query = entityManager.createNativeQuery(
                "select d.family,count(*) " +
                        "from registerform r,device d " +
                        "where r.device=d.deviceId " +
                        "group by d.family");

        List result = query.getResultList();
        List<UsedDeviceFreqResponse> responses = UsedDeviceFreqResponse.res2List(result);

        return responses;
    }

    /**
     * 获得最近4天借出的设备
     */
    @Override
    public List<LastFourDayLentResponse> getLastFourLentDevice() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -3);
        Date now = new Date();
        String currentDate = format.format(now);
        String beforeDate = format.format(calendar.getTime());
        /*
         * 要使用占位符的方式
         */
        Query query = entityManager.createNativeQuery(
                "select substr(borrowTime,1,10) as borrowdate,COUNT(*) from registerform " +
                        " where substr(borrowTime,1,10) between ? and ?" +
                        " group by substr(borrowTime,1,10)"
        );
        query.setParameter(1, beforeDate);
        query.setParameter(2, currentDate);
        List result = query.getResultList();
        /*
         * 如果当天没有借出过设备，结果列表里面，不包含这条记录
         * 先将日期放入hashMap中
         */
        Map<String, Long> map = new LinkedHashMap<>();
        for (int i = -3; i <= 0; i++) {
            // Calendar temp = Calendar.getInstan()         会导致每次得到的日期一样，具体原因可能是因为单例模式
            calendar.setTime(now);
            calendar.add(Calendar.DATE, i);
            String fulldate = format.format(calendar.getTime());
            map.put(fulldate, 0L);
        }
        /*
         * 根据结果，更新haspMap中的数量
         */
        List<LastFourDayLentResponse> responses = new ArrayList<>();
        for (Object object : result) {
            Object[] row = (Object[]) object;
            String date = row[0].toString();
            Long count = Long.parseLong(row[1].toString());
            map.put(date, count);
        }

        /*
         * 将hashmap中的结果放入返回列表中，同时将日期格式改为中文格式
         */
        for (Map.Entry<String, Long> entry : map.entrySet()) {
            String fulldate = entry.getKey();
            String dateAndMonth = fulldate.substring(5);
            String chineseDate = dateAndMonth.replace("-", "月") + "日";
            LastFourDayLentResponse response = new LastFourDayLentResponse(chineseDate, entry.getValue());
            responses.add(response);
        }
        return responses;
    }
}
